贪心算法中必须设定一个贪心准则-----来寻求每一步的最优解,但最后往往不是问题的整体最优解。
问题:假设有n个物品,其体积为V1,V2,V3,V4.......Vn,有若干个体积为V的箱子(理论物品的体积应该小于箱子的体积)
要求把所有物品全部装入箱子中,要求打开的箱子数最少。
分析:怎样合理化分配才能使得打开的箱子数最少呢?首先我们应该把所有的物品体积进行降序排序,先把体积最大的物品进行装箱
第二个物品从第一个箱子进行遍历看第一个箱子剩余的空间是否能容纳此物品,如果可以就装入,如果不可以就再开一个箱子,剩余
的物品依次类推。------------这也就是装箱问题的贪心准则。
声明物品信息的结构体-------物品编号,物品体积
声明物品节点和箱子节点的结构体---------相当于所有打开的箱子拉成了一条链表每个箱子上面的物品又会形成一条链表
#include<stdio.h>
#include<stdlib.h>
#define N 5
#define V 10
typedef struct
{
int gno;//物品编号
int gv;//物品体积
}ElemG;//物品信息
typedef struct node
{
int gno;
struct node *link;
}GoodsLink;//物品节点
typedef struct box
{
int reminder;//剩余体积
GoodsLink *hg;//物品节点的头指针
struct box *next;
}BoxLink;//箱子节点
BoxLink *BinPacking()
{
ElemG *g;
int i,j;
BoxLink *p,*tail,*hbox=NULL;
GoodsLink *new1,*q;
g=(ElemG *)malloc(N *sizeof(ElemG));
//物品信息的初始化
for(i=0;i<N;i++)
{
g[i].gno=i+1;
printf("请输入第%d个物品的体积:",i+1);
scanf("%d",&g[i].gv);
}
//按照体积从大到小降序排序
for(i=0;i<N;i++)
{
int t;
for(j=i+1;j<N;j++)
{
if(g[i].gv<g[j].gv )
{
t=g[i].gno ;
g[i].gno= g[j].gno ;
g[j].gno= t;
t=g[i].gv ;
g[i].gv = g[j].gv ;
g[j].gv = t;
}
}
}
//遍历所有已排序的物品
for(i=0;i<N;i++)
{
//遍历箱子链
for(p=hbox;p&&p->reminder<g[i].gv;p=p->next);
if(!p)//开新箱子(1.第一个物品进入2.遍历箱子后没有一个箱子的剩余空间可以放下此物品)
{
//创建箱子节点
p=(BoxLink *)malloc(sizeof(BoxLink));
//初始化箱子
p->reminder=V;
p->next=NULL;
p->hg=NULL;
if(!hbox)//挂箱子
hbox=tail=p;
else
tail=tail->next=p;
}
//创建物品节点
new1=(GoodsLink *)malloc(sizeof(GoodsLink));
new1->gno=g[i].gno;
new1->link=NULL;
if(!p->hg)//判断要挂的箱子上是不是NULL
p->hg=new1;
else
{
for(q=p->hg;q->link;q=q->link);//遍历箱子节点上的物体尾插
q->link=new1;
}
p->reminder=p->reminder-g[i].gv;//每次放入一个物品都需要算出剩余空间
}
return hbox;
}
int main()
{
BoxLink *p,*hbox;
GoodsLink *q;
int cnt=0;
//输出
hbox=BinPacking();
for(p=hbox;p;p=p->next)
{
printf("第%d个箱子:",++cnt);
for(q=p->hg;q;q=q->link)
printf("%3d",q->gno);
printf("\n");
}
}